package com.yonyou.wdt.job.config;

import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.xxl.job.core.biz.model.ReturnT;
import com.yonyou.wdt.dao.JobLogDao;
import com.yonyou.wdt.entity.QueryDto;
import com.yonyou.wdt.model.JobLogModel;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.request.WdtStockInDtlQueryRequest;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.request.WdtStockOutDtlQueryRequest;
import com.yonyou.wdt.service.YonsuiteService;
import com.yonyou.wdt.utils.RedisUtils;
import com.yonyou.wdt.utils.TenantRateLimiter;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName BaseConfig
 * @Description YS与聚水潭租户信息配置信息
 * @Author HuangWb
 * @Date 2023/11/7 16:00
 */
@Data
@Component
public class BaseConfig {

    // YS 配置信息
    @Value("${ys.config.appKey}")
    private String ysAppKey;
    @Value("${ys.config.appSecret}")
    private String ysAppSecret;
    @Value("${ys.config.tenantId}")
    private String ysTenantId;
    @Resource
    private YonsuiteService yonsuiteService;
    private static Logger logger = LoggerFactory.getLogger(BaseConfig.class);
    @Resource
    public JobLogDao jobLogDao;
    private TenantRateLimiter tenantRateLimiter=new TenantRateLimiter();
    /**
     * @Author Huangwb
     * @Description 接口限流处理
     * @Date 2024/10/23 15:34
     **/
    public void APICurrentLimiting(String apiUrl, int frequency) {
        boolean isNextFlag;
        do {
            // 尝试调用限流器的call方法
            isNextFlag = tenantRateLimiter.getRateLimiter(ysTenantId, apiUrl, frequency).call();
            if (isNextFlag) {
                logger.info("限流中，等待2.5秒再重试...");
                // 如果限流，等待一秒再尝试
                try {
                    Thread.sleep(2500); // 每次限流时等待2.5秒
                } catch (InterruptedException e) {
                    logger.error("Thread Sleep Exception", e);
                }
            }
        } while (isNextFlag); // 当限流时继续循环，直到返回false
    }
    /**
     * @Author Huangwb
     * @Description 查询YS系统租户动态域名信息
     * @Date 2023/10/30 15:45
     **/
    public ReturnT<String> getYsDynamicDomainName(String jobClass,QueryDto ysQueryDto) {
        try {
            String tenantId = ysQueryDto.getTenantId();  // 租户ID
            if (RedisUtils.get(tenantId + ":DynamicDomainName") == null) {
                // 根据租户ID查询动态域名
                JSONObject dynamicDomainName = yonsuiteService.getDynamicDomainName(null, tenantId);
                if (null != dynamicDomainName && !dynamicDomainName.isEmpty()) {
                    // 将动态域名存入Redis
                    RedisUtils.set(tenantId + ":DynamicDomainName", dynamicDomainName, 86400 * 30);
                } else {
                    logger.error("查询租户【{}】动态域名失败，请重试", tenantId);
                    // insertXxlJobLog(null, "0", "租户：【" + tenantId + "】获取动态域名失败，请稍后重试", jobClassType);
                    InsertLogger(jobClass,null, "0", "获取动态域名失败");
                    return new ReturnT<>(ReturnT.FAIL_CODE, "查询租户【" + tenantId + "】动态域名失败，请重试");
                }
            }
            // 获取Redis中指定租户动态域名
            JSONObject dynamicDomainNameRedis = (JSONObject) RedisUtils.get(tenantId + ":DynamicDomainName");
            ysQueryDto.setGatewayUrl(dynamicDomainNameRedis.getStr("gatewayUrl"));
            ysQueryDto.setTokenUrl(dynamicDomainNameRedis.getStr("tokenUrl"));
            return null;
        } catch (Exception e) {
            return new ReturnT<>(ReturnT.FAIL_CODE, "获取动态域名失败：" + e.getMessage());
        }
    }
    public void InsertLogger(String jobClass,String code, String oneL, String mags) {  // 单据编号、是否成功、详细信息
        try {
            JobLogModel jobLogDTO = new JobLogModel();
            jobLogDTO.setJobClass(jobClass);
            jobLogDTO.setJobCode(code);
            jobLogDTO.setJobTime(new Date());
            jobLogDTO.setJobResult(oneL);
            jobLogDTO.setJobResultMessage(mags);
            jobLogDTO.setJobLogUser("maoer");
            jobLogDao.insertJobLog(jobLogDTO);
        } catch (Exception e) {
            logger.error("插入日志错误：" + e.getMessage());
        }
    }

    /**
     * @param jsonObject
     * @param dto
     * @return 采购订单列表查询返回值
     */
    public ArrayList<JSONObject> getYsPurchaseRecord(JSONObject jsonObject, QueryDto dto) throws Exception {
        HashMap<String, Object> purQueryMap = new HashMap<>();
        purQueryMap.put("pageSize", 100);
        purQueryMap.put("status", "1");  // 单据状态
        purQueryMap.put("isSum", false);  // 查询表头
        purQueryMap.put("pageIndex", 1);
        ArrayList<Map<String, Object>> simpleVOsList = new ArrayList<>();
        HashMap<String, Object> simpleVOsMaps = new HashMap<>();
        simpleVOsMaps.put("field", "code");
        simpleVOsMaps.put("op", "eq");
        String purCode= jsonObject.getStr("src_order_no");
        String outerNo= jsonObject.getStr("outer_no");
        String apiOuterNo = jsonObject.getStr("pr_api_outer_no");
        if (StringUtils.isNotBlank(apiOuterNo) && apiOuterNo.startsWith("PO")){
            purCode=apiOuterNo;
        }else if (StringUtils.isNotBlank(outerNo) && outerNo.startsWith("PO")){
            purCode=outerNo;
        }
        simpleVOsMaps.put("value1", purCode);
        simpleVOsList.add(simpleVOsMaps);
        purQueryMap.put("simpleVOs", simpleVOsList);

        JSONObject purJson = yonsuiteService.purOrderList(purQueryMap, dto);
        ArrayList<JSONObject> purList = new ArrayList<>();
        if ("200".equals(purJson.getStr("code"))) {
            if (null != purJson.getJSONObject("data") && null != purJson.getJSONObject("data").getJSONArray("recordList")) {
                JSONArray purJsonArray = purJson.getJSONObject("data").getJSONArray("recordList");
                //判断是否有YS的采购订单关联
                if (purJson.getJSONObject("data").getLong("recordCount") != 0) {
                    for (Object pur : purJsonArray) {
                        purList.add((JSONObject) pur);
                    }
                } else {
                    logger.error(jsonObject.get("purchase_no") + "：采购订单没有查询到对应单据");
                    return new ArrayList<>();
                }
            }
        }
        return purList;
    }

    public WdtStockOutDtlQueryRequest setStockOutDtlModel(Map<String, Object> param, String targetAppKey, String sid) {
        WdtStockOutDtlQueryRequest req = new WdtStockOutDtlQueryRequest();
        //旺店通的奇门appkey
        req.setTargetAppKey(targetAppKey);
        //旺店通erp的卖家账号
        req.setSid(sid);
        String startTime = MapUtil.getStr(param, "start_time");
        if (StringUtils.isNotBlank(startTime)) {
            req.setStartTime(startTime);
        }
        String endTime = MapUtil.getStr(param, "end_time");
        if (StringUtils.isNotBlank(endTime)) {
            req.setEndTime(endTime);
        }
        String srcOrderNo = MapUtil.getStr(param, "src_order_no");
        if (StringUtils.isNotBlank(srcOrderNo)) {
            req.setSrcOrderNo(srcOrderNo);
        }
        String stockoutNo = MapUtil.getStr(param, "stockout_no");
        if (StringUtils.isNotBlank(stockoutNo)) {
            req.setStockoutNo(stockoutNo);
        }
        if (param.containsKey("page_no")) {
            req.setPageNo(MapUtil.getLong(param, "page_no"));
        }
        if (param.containsKey("page_size")) {
            req.setPageSize(MapUtil.getLong(param, "page_size"));
        }
        return req;
    }

    public WdtStockInDtlQueryRequest setStockInDtlModel(Map<String, Object> param, String targetAppKey, String sid) {
        WdtStockInDtlQueryRequest req = new WdtStockInDtlQueryRequest();
        //旺店通的奇门appkey
        req.setTargetAppKey(targetAppKey);
        //旺店通erp的卖家账号
        req.setSid(sid);
        String startTime = MapUtil.getStr(param, "start_time");
        if (StringUtils.isNotBlank(startTime)) {
            req.setStartTime(startTime);
        }
        String endTime = MapUtil.getStr(param, "end_time");
        if (StringUtils.isNotBlank(endTime)) {
            req.setEndTime(endTime);
        }
        String srcOrderNo = MapUtil.getStr(param, "src_order_no");
        if (StringUtils.isNotBlank(srcOrderNo)) {
            req.setSrcOrderNo(srcOrderNo);
        }
        String stockinNo = MapUtil.getStr(param, "stockin_no");
        if (StringUtils.isNotBlank(stockinNo)) {
            req.setStockinNo(stockinNo);
        }
        if (param.containsKey("page_no")) {
            req.setPageNo(MapUtil.getLong(param, "page_no"));
        }
        if (param.containsKey("page_size")) {
            req.setPageSize(MapUtil.getLong(param, "page_size"));
        }
        return req;
    }
}
